<?php

namespace Sharks\Core\Persistence\Cache;

use PHPSQLParser\PHPSQLParser;
use Sharks\Core\AppContext;
use Sharks\Core\Support\Base\Argument;
use Sharks\Core\Support\Cache\CacheFactory;
use Sharks\Core\Support\Cache\FileCache;

/**
 * Database缓存
 */
abstract class DatabaseCacheProvider {
    protected static $parser;

    /**
     * 判断SQL语句中,是否涉及指定的数据表
     * @param $sql
     * @param array|null $tables
     * @return mixed
     */
    public abstract function has($sql, array $tables = null);

    public abstract function get($sql, array $tables = null);

    public abstract function put($sql, $cacheableValue, array $tables = null);

    public abstract function changeByQuery($sql);

    public abstract function change($table);

    public abstract function changes(array $tables);

    /**
     * 从SQL中解析出涉及的表
     * @param $sql
     * @return array|mixed
     */
    public function getTablesByQuery($sql) {
        if (empty($sql)) {
            return array();
        }

        $filecache = CacheFactory::fileCache();
        if ($filecache->isExisting($sql . '_FORTABLE')) {
            return $filecache->get($sql . '_FORTABLE');
        }

        // analyze sql' table usage, and then change the table's tag
        if (is_null(self::$parser)) {
            self::$parser = new PHPSQLParser();
        }
        $parsed = self::$parser->parse($sql);
        if (isset($parsed['SELECT'])) {
            $tables = array();
            self::resolveTable($parsed, $tables);

            $filecache->set($sql . '_FORTABLE', $tables);
            return $tables;
        }
        return array();
    }

    /**
     * 从 PHPSQLParser 解析集中解析出涉及的表
     * @param array $parsed
     * @param array $resolves
     */
    public function resolveTable(array $parsed, array &$resolves) {
        foreach ($parsed as $item) {
            if (isset($item['table'])) {
                $resolves[] = $item['table'];
            }
            elseif (is_array($item)) {
                self::resolveTable($item, $resolves);
            }
        }
    }
}